/*
 *
 * System2 Simulation Framework
 * Copyright (C) 2011 - 2012 Jacob Dawid
 * jacob.dawid@googlemail.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "value.h"

namespace System2 {
    Value::Value() {
        m_isValid = false;
        m_number = Number(0.0);
        m_unit = Unit();
    }

    Value::Value(Number number, Unit unit) {
        assign(number, unit);
    }

    Value::Value(const Value& other) {
        assign(other);
    }

    QString Value::toString() {
        return QString("%1%2").arg((double)m_number).arg(m_unit.toString());
    }

    bool Value::translateToUnit(const Unit& unit) {
        if(m_unit.isCompatibleWith(unit)) {
            m_number *= m_unit.adapt(unit);
            return true;
        }
        return false;
    }

    bool Value::isValid() const {
        return m_isValid;
    }

    void Value::assign(const Value &other) {
        m_number = other.m_number;
        m_unit = other.m_unit;
        m_isValid = other.m_isValid;
    }

    void Value::assign(Number number, Unit unit) {
        m_isValid = true;
        m_number = number;
        m_unit = unit;
    }

    bool Value::isEqualTo(const Value &other) {
        if(m_unit.isCompatibleWith(other.m_unit)) {
            Value testValue(*this);
            testValue.translateToUnit(other.m_unit);
            if(testValue.m_unit == other.m_unit)
                if(testValue.m_number == other.m_number)
                    return true;
        }
        return false;
    }

    void Value::add(const Value& other) {
        if(!isValid() || !other.isValid()) {
            m_isValid = false;
            return;
        }

        if(other.m_unit.isCompatibleWith(other.m_unit)) {
            if(translateToUnit(other.m_unit)) {
                m_isValid = true;
                m_number += other.m_number;
            }
        }
        m_isValid = false;
    }

    void Value::subtract(const Value& other) {
        if(!isValid() || !other.isValid()) {
            m_isValid = false;
            return;
        }

        if(other.m_unit.isCompatibleWith(other.m_unit)) {
            if(translateToUnit(other.m_unit)) {
                m_isValid = true;
                m_number -= other.m_number;
            }
        }
        m_isValid = false;
    }

    void Value::multiply(Number number) {
        m_number *= number;
    }

    void Value::divide(Number number) {
        m_number /= number;
    }
}
